from functools import wraps
import json

from django.core.paginator import Paginator
from django.db.models import Q, F
from django.http import JsonResponse
from django.utils import timezone

# Create your views here.
from apps.news.models import NewsInfo
from apps.user.models import UserInfo


# 检测请求方式装饰器
def check_method(func):
    @wraps(func)
    def is_post(request):
        if request.method != 'POST':
            result = {'code': 401, 'error': '请求方式错误！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
        else:
            # 取出请求的body体并把json格式转为python字典形式
            json_obj = json.loads(request.body)
            return func(request, json_obj)

    return is_post


# 创建资讯
def create_news_view(request):
    if request.method != 'POST':
        result = {'code': 401, 'error': '请求方式错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
    else:
        try:
            file = request.FILES['newsCover']
            json_obj = json.loads(request.POST['data'])
            user_name = json_obj['userName']
            news_name = json_obj['newsName']
            news_tag = json_obj['newsTag']
            news_detail = json_obj['newsDetail']
        except Exception as e:
            print(e)
            result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )

        try:
            user_obj = UserInfo.objects.get(user_name=user_name)
            if not user_obj.is_management:
                result = {'code': 403, 'error': '用户权限不够！'}
                return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
            else:
                file.name = f'{timezone.now()} + {user_obj.phone}.jpg'
                news_obj = NewsInfo(news_name=news_name, news_initiator=user_obj)
                news_obj.news_initiator_phone = user_obj.phone
                news_obj.news_tag = news_tag
                news_obj.news_detail = news_detail
                news_obj.news_cover = file
                news_obj.save()

                result = {'code': 200, 'success': '创建资讯成功！'}
                return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
        except Exception as e:
            print(e)
            result = {'code': 403, 'error': '用户不存在！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 进入首页推荐收藏最多的5条资讯
def index_recommend_view(request):
    news_obj = NewsInfo.objects.exclude(Q(news_status='0') | Q(news_status='1')).order_by('-news_collect_num').values()
    list_news_obj = list(news_obj)
    data = []

    if len(list_news_obj) == 0:
        result = {'code': 403, 'error': '暂无资讯！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
    elif len(list_news_obj) < 5:
        for i in list_news_obj:
            data.append(i)
    else:
        for i in range(0, 5):
            data.append(list_news_obj[i])

    result = {'code': 200, 'data': data}
    return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 资讯页请求对应页码的资讯信息
@check_method
def news_page_view(request, json_obj):
    try:
        page = json_obj['page']
        news_obj = NewsInfo.objects.exclude(Q(news_status='0') | Q(news_status='1')).values()

        if len(news_obj) == 0:
            result = {'code': 403, 'error': '暂无资讯！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
        elif len(news_obj) < 2:
            paginator = Paginator(news_obj, len(news_obj))
        else:
            paginator = Paginator(news_obj, 2)

        page_num = paginator.num_pages
        page_obj = paginator.page(page)
        return JsonResponse({'code': 200, 'data': list(page_obj.object_list), 'pageNum': page_num})
    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 资讯详情 改动
@check_method
def news_detail_view(request, json_obj):
    try:
        news_id = json_obj['id']

        news_objs = list(NewsInfo.objects.filter(id=news_id))
        news_obj = list(NewsInfo.objects.filter(id=news_id).values())

        collect_users = list(news_objs[0].news_collect_id.all().values())

        result = {'code': 200, 'data': list(news_obj), 'collecter': collect_users}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 查看自己发起的资讯
@check_method
def self_news_view(request, json_obj):
    try:
        user_name = json_obj['userName']
        try:
            user_obj = UserInfo.objects.get(user_name=user_name)

            if user_obj.is_management:
                self_news_obj = user_obj.news_initiator_id.all().values()

                result = {'code': 200, 'data': list(self_news_obj)}
                return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
            else:
                result = {'code': 403, 'error': '权限不足！'}
                return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
        except Exception as e:
            print(e)
            result = {'code': 403, 'error': '用户不存在！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 收藏资讯
@check_method
def collect_news_view(request, json_obj):
    try:
        news_id = json_obj['id']
        user_name = json_obj['userName']
        try:
            news_obj = NewsInfo.objects.get(id=news_id)
            user_obj = UserInfo.objects.get(user_name=user_name)

            is_collected = len(news_obj.news_collect_id.filter(id=user_obj.id).values())

            if not is_collected:
                news_obj.news_collect_id.add(user_obj)
                news_obj.news_collect_num = F('news_collect_num') + 1
                news_obj.save()

                result = {'code': 200, 'success': '收藏成功！'}
                return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
            else:
                result = {'code': 403, 'error': '已收藏过！'}
                return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
        except Exception as e:
            print(e)
            result = {'code': 403, 'error': '用户或资讯不存在！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )

    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 查看自己收藏的资讯
@check_method
def self_collect_news_view(request, json_obj):
    try:
        user_name = json_obj['userName']
        try:
            user_obj = UserInfo.objects.get(user_name=user_name)

            self_collect_news_obj = user_obj.collect_news.exclude(Q(news_status='0') | Q(news_status='1')).values()

            result = {'code': 200, 'data': list(self_collect_news_obj)}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
        except Exception as e:
            print(e)
            result = {'code': 403, 'error': '用户不存在！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 取消收藏
@check_method
def cancle_collect_news_view(request, json_obj):
    try:
        news_id = json_obj['id']
        user_name = json_obj['userName']
    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )

    try:
        news_obj = NewsInfo.objects.get(id=news_id)
        user_obj = UserInfo.objects.get(user_name=user_name)

        is_collected = len(news_obj.news_collect_id.filter(id=user_obj.id).values())

        if is_collected:
            news_obj.news_collect_id.remove(user_obj)
            news_obj.news_collect_num = F('news_collect_num') - 1
            news_obj.save()

            result = {'code': 200, 'success': '取消收藏成功！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
        else:
            result = {'code': 403, 'error': '还未收藏！'}
            return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
    except Exception as e:
        print(e)
        result = {'code': 403, 'error': '用户或资讯不存在！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 删除资讯
@check_method
def del_news_view(request, json_obj):
    try:
        news_id = json_obj['id']
    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )

    NewsInfo.objects.filter(id=news_id).update(news_status='1')

    result = {'code': 200}
    return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )


# 搜索资讯
@check_method
def search_news(request, json_obj):
    try:
        search_text = json_obj['search_text']
    except Exception as e:
        print(e)
        result = {'code': 402, 'error': '未获取到数据或数据变量名错误！'}
        return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )

    news_objs = NewsInfo.objects.filter(news_name__contains=search_text).values()

    result = {'code': 200, 'data': list(news_objs)}
    return JsonResponse(result, json_dumps_params={"ensure_ascii": False}, )
